import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, 
                             QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QComboBox)
from PyQt5.QtGui import QFont

class RiskCalculator(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.initLogic()

    def initUI(self):
        self.setWindowTitle("急性呼吸困难患者30天死亡风险评分计算器")
        self.resize(800, 600)
        main_layout = QVBoxLayout()

        # —— 界面简介 ——
        self.intro_layout = QVBoxLayout()
        self.intro_label = QLabel("""简介：本计算器用于帮助医疗专家估计急性呼吸困难患者30天死亡风险。
请输入患者的相关健康数据，点击"生成风险评分"按钮获取预测结果。
请注意：该结果仅供参考，不应替代医疗专家的专业判断和建议。""")
        self.intro_label.setWordWrap(True)
        self.intro_label.setFont(QFont("Arial", 10))
        self.intro_layout.addWidget(self.intro_label)
        main_layout.addLayout(self.intro_layout)


        # —— 年龄输入 ——
        self.age_layout = QVBoxLayout()
        self.age_label = QLabel("年龄（周岁）：")
        self.age_input = QLineEdit()
        self.age_input.setPlaceholderText("请输入患者年龄（如65）")
        self.age_layout.addWidget(self.age_label)
        self.age_layout.addWidget(self.age_input)
        main_layout.addLayout(self.age_layout)


        # —— 收缩压输入 ——
        self.sbp_layout = QVBoxLayout()
        self.sbp_label = QLabel("收缩压（mmHg）：")
        self.sbp_input = QLineEdit()
        self.sbp_input.setPlaceholderText("请输入收缩压数值（如130）")
        self.sbp_layout.addWidget(self.sbp_label)
        self.sbp_layout.addWidget(self.sbp_input)
        main_layout.addLayout(self.sbp_layout)


        # —— 肾功能不全（下拉筛选框） ——
        self.renal_layout = QVBoxLayout()
        self.renal_label = QLabel("肾功能不全：")
        self.renal_combo = QComboBox()  # 替换为下拉框
        # 添加选项：显示文本 + 实际值（通过setItemData绑定）
        self.renal_combo.addItem("否", 0)  # 显示“否”，实际值0
        self.renal_combo.addItem("是", 1)  # 显示“是”，实际值1
        self.renal_layout.addWidget(self.renal_label)
        self.renal_layout.addWidget(self.renal_combo)
        main_layout.addLayout(self.renal_layout)


        # —— 氧疗方式（下拉筛选框） ——
        self.oxygen_layout = QVBoxLayout()
        self.oxygen_label = QLabel("氧疗方式：")
        self.oxygen_combo = QComboBox()  # 替换为下拉框
        # 添加选项：显示文本 + 实际值
        self.oxygen_combo.addItem("未吸氧", 0)
        self.oxygen_combo.addItem("鼻导管吸氧", 1)
        self.oxygen_combo.addItem("面罩吸氧", 2)
        self.oxygen_combo.addItem("机械通气", 3)
        #self.oxygen_combo.addItem("4 有创呼吸机", 4)  # 补充原缺失的选项
        self.oxygen_layout.addWidget(self.oxygen_label)
        self.oxygen_layout.addWidget(self.oxygen_combo)
        main_layout.addLayout(self.oxygen_layout)


        # —— 生成结果按钮 ——
        self.calc_btn = QPushButton("生成风险评分")
        self.calc_btn.setFont(QFont("Arial", 12))
        self.calc_btn.setStyleSheet("""
            background-color: #4CAF50;
            color: white;
            padding: 8px;
            border-radius: 4px;
        """)
        main_layout.addWidget(self.calc_btn)


        # —— 结果显示区域 ——
        self.result_label = QLabel("计算结果将显示在这里")
        self.result_label.setFont(QFont("Arial", 14))
        self.result_label.setWordWrap(True)
        main_layout.addWidget(self.result_label)


        # —— 作者信息 ——
        self.author_layout = QHBoxLayout()
        self.author_label = QLabel("作者：范文强\n参考：急诊科急性呼吸困难患者30天死亡风险预测")
        self.author_label.setWordWrap(True)
        self.author_label.setFont(QFont("Arial", 9))
        self.author_layout.addWidget(self.author_label)
        main_layout.addLayout(self.author_layout)


        self.setLayout(main_layout)


    def initLogic(self):
        self.calc_btn.clicked.connect(self.calculate)


    def calculate(self):
        try:
            # 1. 获取输入值（分类变量从下拉框取实际值）
            age = float(self.age_input.text().strip())
            sbp = float(self.sbp_input.text().strip())
            renal = self.renal_combo.currentData()  # 直接获取绑定的数值（0或1）
            oxygen = self.oxygen_combo.currentData()  # 获取氧疗方式数值（0-4）


            # 2. 列线图映射规则（保持原公式）
            age_points = 0.8 * age - 16
            sbp_points = -0.5 * sbp + 130
            renal_points = 24.5 if renal == 1 else 0
            # 氧疗方式Points映射（补充4对应的分值，原字典缺少）
            oxygen_map = {0:0, 1:32, 2:53, 3:75}  # 假设4对应90分，需按实际校准
            oxygen_points = oxygen_map[oxygen]


            # 3. 计算总Points和风险值
            total_points = age_points + sbp_points + renal_points + oxygen_points
            risk = 0.01 * total_points - 1.3
            # 风险值边界处理（确保在0-100%范围内）
            risk = max(0, min(risk, 0.8))


            # 4. 显示结果
            self.result_label.setText(f"""
计算结果：
1. 年龄对应Points：{age_points:.1f}
2. 收缩压对应Points：{sbp_points:.1f}
3. 肾功能不全对应Points：{renal_points:.1f}
4. 氧疗方式对应Points：{oxygen_points:.1f}
——————
总Points：{total_points:.1f}
30天死亡风险预测：{risk:.2%}（仅供参考）
            """.strip())


        except ValueError:
            self.result_label.setText("错误：年龄和收缩压请输入有效的数字！")
        except Exception as e:
            self.result_label.setText(f"计算出错：{str(e)}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    window = RiskCalculator()
    window.show()
    sys.exit(app.exec_())
